package com.rm.zeyou.pay.alipay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rm.zeyou.constant.NumberConstants;
import com.rm.zeyou.constant.OrderConstants;
import com.rm.zeyou.entity.UserItemOrder;
import com.rm.zeyou.entity.UserMemberOrder;
import com.rm.zeyou.exception.ErrorCodeException;
import com.rm.zeyou.exception.ErrorCodeExceptionEnum;
import com.rm.zeyou.mapper.UserMemberOrderMapper;
import com.rm.zeyou.mapper.ZfbpayConfigMapper;
import com.rm.zeyou.pay.alipay.entity.AlipayEntity;
import com.rm.zeyou.pay.alipay.service.AiliPayNotifyService;
import com.rm.zeyou.service.UserItemOrderService;
import com.rm.zeyou.util.check.CheckEmptyUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *
 */
@Log4j2
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class AiliPayNotifyServiceImpl implements AiliPayNotifyService {
    @Resource
    private AlipayEntity alipayEntity;

    @Resource
    private UserItemOrderService userItemOrderService;
    @Resource
    private UserMemberOrderMapper userMemberOrderMapper;
    @Resource
    private ZfbpayConfigMapper zfbpayConfigMapper;


    /**
     * 常规服务订单回掉
     *
     * @param request
     * @return
     * @throws AlipayApiException
     */
    @Override
    public String notify(HttpServletRequest request) throws Exception {
        log.info("支付宝支付 常规服务订单回掉");
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        log.info("支付宝回调返回的信息：{}", params.toString());
        // 校验支付宝回掉签名
        String publicKey = zfbpayConfigMapper.selectOneData("PublicKey");
        boolean flag = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", alipayEntity.getSignType());
        log.info("支付宝回调返回签名校验状态：{}", flag);
        ///支付成功
        if (flag) {
            log.info("支付成功");

        } else {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.VERIFY_ERROR);
        }

        /**
         * 处理业务逻辑
         * TODO
         */
        String orderNo = params.get("out_trade_no");
        log.info("订单编号:{}", orderNo);
        String payerTotal = params.get("total_amount");
        log.info("支付金额:{}", payerTotal);

        UserItemOrder userItemOrder = userItemOrderService.getOne(new LambdaQueryWrapper<UserItemOrder>()
                .eq(UserItemOrder::getOrderNo, orderNo));
        if (new BigDecimal(payerTotal).compareTo(userItemOrder.getNeedPayPrice()) != 0) {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.PAY_PRICE_ERROR);
        }
        if (userItemOrder.getOrderStatus().equals(OrderConstants.ORDER_STATUS_PENDING_PAYMENT)) {
            userItemOrderService.updateOrder(userItemOrder.getOrderNo(), userItemOrder.getPayType());
        }


        /**
         * 答应支付宝
         */
        return "success";

    }

    @Override
    public String rechargeNotify(HttpServletRequest request) throws AlipayApiException {
        log.info("支付宝支付 开通会员回掉");
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        log.info("支付宝回调返回的信息：{}", params.toString());
        // 校验支付宝回掉签名
        String publicKey = zfbpayConfigMapper.selectOneData("PublicKey");
        boolean flag = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", alipayEntity.getSignType());
        log.info("支付宝回调返回签名校验状态：{}", flag);
        ///支付成功
        if (flag) {
            log.info("支付成功");

        } else {
            log.info("支付失败");
        }

        /**
         * 处理业务逻辑
         * TODO
         */
        String orderNo = params.get("out_trade_no");
        String totalAmount = params.get("total_amount");
        BigDecimal yuan = new BigDecimal(totalAmount);

        UserMemberOrder userMemberOrder = userMemberOrderMapper.selectOne(new LambdaQueryWrapper<UserMemberOrder>().eq(UserMemberOrder::getRechangeOrderNo, orderNo));
        if (CheckEmptyUtil.isEmpty(userMemberOrder)) {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.ORDER_EMPTY);
        }
        if (yuan.compareTo(userMemberOrder.getPayPrice()) != 0) {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.PAY_PRICE_ERROR);
        }
        if (userMemberOrder.getPayStatus().equals(NumberConstants.ZERO_CONSTANTS)){
            //修改订单支付状态
            userMemberOrder.setPayStatus(NumberConstants.ONE_CONSTANTS);
            userMemberOrderMapper.updateById(userMemberOrder);
            userItemOrderService.payVip(userMemberOrder.getUserId(), userMemberOrder.getMemberType(), userMemberOrder.getEffectDay());

        }

        /**
         * 答应支付宝
         */
        return "success";
    }

    @Override
    public String upgradeNotify(HttpServletRequest request) throws AlipayApiException {
        log.info("支付宝支付 升级服务订单回掉");
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        log.info("支付宝回调返回的信息：{}", params.toString());
        // 校验支付宝回掉签名
        String publicKey = zfbpayConfigMapper.selectOneData("PublicKey");
        boolean flag = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", alipayEntity.getSignType());
        log.info("支付宝回调返回签名校验状态：{}", flag);
        ///支付成功
        if (flag) {
            log.info("支付成功");

        } else {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.VERIFY_ERROR);
        }

        /**
         * 处理业务逻辑
         * TODO
         */
        String orderNo = params.get("out_trade_no");
        log.info("订单编号:{}", orderNo);
        String payerTotal = params.get("total_amount");
        log.info("支付金额:{}", payerTotal);

        UserItemOrder userItemOrder = userItemOrderService.getOne(new LambdaQueryWrapper<UserItemOrder>()
                .eq(UserItemOrder::getOrderNo, orderNo));
        if (new BigDecimal(payerTotal).compareTo(userItemOrder.getNeedPayPrice()) != 0) {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.PAY_PRICE_ERROR);
        }
        userItemOrderService.upgradeUpdateOrder(userItemOrder.getOrderNo(), userItemOrder.getPayType());

        /**
         * 答应支付宝
         */
        return "success";
    }

    @Override
    public String bellNotify(HttpServletRequest request) throws AlipayApiException {
        log.info("支付宝支付 加钟服务订单回掉");
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        log.info("支付宝回调返回的信息：{}", params.toString());
        // 校验支付宝回掉签名
        String publicKey = zfbpayConfigMapper.selectOneData("PublicKey");
        boolean flag = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", alipayEntity.getSignType());
        log.info("支付宝回调返回签名校验状态：{}", flag);
        ///支付成功
        if (flag) {
            log.info("支付成功");

        } else {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.VERIFY_ERROR);
        }

        /**
         * 处理业务逻辑
         * TODO
         */
        String orderNo = params.get("out_trade_no");
        log.info("订单编号:{}", orderNo);
        String payerTotal = params.get("total_amount");
        log.info("支付金额:{}", payerTotal);

        UserItemOrder userItemOrder = userItemOrderService.getOne(new LambdaQueryWrapper<UserItemOrder>()
                .eq(UserItemOrder::getOrderNo, orderNo));
        if (new BigDecimal(payerTotal).compareTo(userItemOrder.getNeedPayPrice()) != 0) {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.PAY_PRICE_ERROR);
        }
        userItemOrderService.bellUpdateOrder(userItemOrder.getOrderNo(), userItemOrder.getPayType());

        /**
         * 答应支付宝
         */
        return "success";
    }


}
